
#ifndef BUFFER_H
#define BUFFER_H

namespace fx {

    class Buffer
    {
    public:
        Buffer();
        Buffer(const Buffer& another);
        explicit Buffer(boost::uint32_t length);
        Buffer(const boost::uint8_t* data, boost::uint32_t length);
        Buffer(const std::string& str);

    public:
        Buffer& operator = (const Buffer& another);
        bool operator ! () const;
        operator bool () const;

    public:
        void Resize(boost::uint32_t length);
        void Swap(Buffer& another);

        boost::uint32_t Length() const { return length_; }
        boost::uint8_t* Data() { return length_ ? (data_.get() + offset_) : NULL; }
        const boost::uint8_t* Data() const { return length_ ? (data_.get() + offset_) : NULL; }
        std::string AsString() const { return length_ ? std::string((const char*)Data(), Length()) : ""; }

    private:
        boost::shared_array<boost::uint8_t> data_;
        boost::uint32_t offset_;
        boost::uint32_t length_;

    };

    inline bool operator < (const Buffer& a, const Buffer& b) {
        return a.Data() < b.Data() ||
            (a.Data() == b.Data() && a.Length() < b.Length());
    }
    inline bool operator == (const Buffer& a, const Buffer& b) {
        return a.Data() == b.Data() && a.Length() == b.Length();
    }
    inline bool operator != (const Buffer& a, const Buffer& b) {
        return a.Data() != b.Data() || a.Length() != b.Length();
    }

}

#endif//BUFFER_H
